<script>
import {
  Document,
  DocumentAdd,
  FolderAdd,
  FolderOpened,
  Key,
  More,
  MoreFilled,
  Plus,
  Tickets,
} from "@element-plus/icons-vue";
import { MindMapping } from "@icon-park/vue-next";
import request from "../../../utils/Request.js";
import { ElMessage, ElMessageBox } from "element-plus";
import store from "../../../store/index.js";
import EditTab from "./EditTab.vue";
import EditMarkdown from "./MarkdownEdit.vue";

export default {
  name: "Edit",
  components: {
    EditMarkdown,
    EditTab,
    DocumentAdd,
    FolderAdd,
    Tickets,
    MoreFilled,
    More,
    Key,
    Document,
    FolderOpened,
    Plus,
    MindMapping,
  },
  data() {
    return {
      projectName: "知识库名称",
      data: [
        {
          id: "12345",
          name: "文件",
          type: "rtf",
        },
        {
          name: "文件夹",
          children: [],
          type: "folder",
        },
        {
          name: "文件夹1",
          type: "folder",
          children: [
            {
              name: "文件",
              type: "markdown",
            },
            {
              name: "文件夹",
              children: [],
              type: "folder",
            },
            {
              name: "文件夹2",
              type: "folder",
              children: [
                {
                  name: "123",
                  type: "api",
                },
              ],
            },
          ],
        },
      ],
      defaultProps: {
        children: "children",
        label: "name",
        class: (data, node) => {
          return "my-tree-node";
        },
      },
      moreVisibleList: new Array(7).fill(false),
      treeLoading: false,
      createDialogVisible: false,
      createDialogTabName: "doc",
      createData: {
        projectId: this.$route.params.projectId,
        name: "",
        type: "api",
        parentFolderId: null,
        order: 0,
      },
      createRules: {
        name: [
          { required: true, message: "请取个名字吧", trigger: "blur" },
          { min: 1, max: 64, message: "你这个名字有点长啊", trigger: "blur" },
        ],
        type: [
          { required: true, message: "请选择文档类型", trigger: "blur" },
          {
            validator: (rule, value, callback) => {
              if (
                value !== "api" &&
                value !== "markdown" &&
                value !== "rtf" &&
                value !== "folder" && 
                value !== "mindmap"
              )
                callback(new Error("请选择正确的文档类型"));
              else callback();
            },
          },
        ],
      },
      renameDialogVisible: false,
      renameDialogTitleSuffix: "",
      renameData: {
        id: null,
        projectId: this.$route.params.projectId,
        name: "",
        type: "api",
      },
      tempNodeData: null,
      expandedKeys: [],
      orderData: {
        id: null,
        type: "",
        parentFolderId: null,
        order: 0,
      },
      tabPlaneData: [
        {
          id: "1713536186400145410",
          name: "米哈有",
          type: "markdown",
        },
        {
          id: "123",
          name: "123米哈有",
          type: "api",
        },
        {
          id: "1234",
          name: "1234米哈有",
          type: "rtf",
        },
      ],
      selectTabName: "",
    };
  },
  methods: {
    /**
     * 删除
     * @param doc
     */
    deleteDoc(doc) {
      ElMessageBox.confirm(
        "是否要删除" +
          (doc.type === "folder" ? '目录"' : '文档"') +
          doc.name +
          '"?',
        "删除警告",
        {
          confirmButtonText: "删除",
          cancelButtonText: "取消",
          type: "warning",
        }
      ).then(() => {
        // delete
        request({
          url: "/api/project/doc/delete",
          method: "post",
          data: {
            id: doc.id,
            projectId: this.$route.params.projectId,
            type: doc.type,
          },
        }).then(({ data }) => {
          if (data.code === 0) {
            this.getDocList();
            store.state.needRemoveTabId = doc.id;
            ElMessage.success("删除成功");
          } else {
            ElMessage.error(data.msg);
          }
        });
      });
    },

    /**
     * 重命名
     */
    renameDoc() {
      let form = this.$refs["renameFormRef"];

      form.validate((isValid) => {
        if (isValid) {
          if (this.renameData.name === this.renameDialogTitleSuffix) {
            ElMessage.error("名字与之前相同");
            return;
          }

          request({
            url: "/api/project/doc/rename",
            method: "post",
            data: this.renameData,
          }).then(({ data }) => {
            if (data.code === 0) {
              this.tempNodeData.name = this.renameData.name;
              this.tempNodeData = null;
              this.renameDialogVisible = false;
              ElMessage.success("重命名成功");
            } else {
              ElMessage.error(data.msg);
            }
          });
        }
      });
    },

    openRenameDialog(data) {
      // 初始化renameData
      this.renameData.type = data.type;
      this.renameData.id = data.id;
      this.renameData.name = data.name;

      this.renameDialogTitleSuffix = data.name;
      this.renameDialogVisible = true;
      this.tempNodeData = data;
    },
    openCreateDialog(tabName, data) {
      // 设置父层目录ID
      this.createData.parentFolderId = data === null ? null : data.id;
      // 设置排序为最后
      if (this.createData.parentFolderId === null) {
        // 1000 为order的步长，为了减少移动文档时order改变对其它文档order的变更。
        this.createData.order =
          this.data.length === 0
            ? 0
            : this.data[this.data.length - 1].order + 1000;
      } else {
        // 1000 同上
        this.createData.order =
          data.children == null || data.children.length === 0
            ? 0
            : data.children[data.children.length - 1].order + 1000;
      }

      this.createDialogTabName = tabName;
      this.createDialogVisible = true;
    },

    createDoc() {
      let form = this.$refs[this.createDialogTabName + "FormRef"];

      if (this.createDialogTabName === "folder")
        this.createData.type = "folder";

      form.validate((isValid) => {
        if (isValid) {
          request({
            url: "/api/project/doc/create",
            method: "post",
            data: this.createData,
          }).then(({ data }) => {
            if (data.code === 0) {
              this.getDocList();
              this.createDialogVisible = false;
            } else {
              ElMessage.error(data.msg);
            }
          });
        }
      });
    },

    getDocList(first = false) {
      request({
        url: "/api/project/doc/list",
        method: "get",
        params: {
          projectId: this.$route.params.projectId,
        },
      }).then(({ data }) => {
        if (data.code === 0) {
          this.saveLastExpandedNodeKeys();
          this.data = data.data;
          this.treeLoading = false;
          if (first) {
            this.tabPlaneData = [];
            store.state.planeTabIsModified = [];
          }
        } else {
          ElMessage.error("加载文档列表时出现问题");
        }
      });
    },

    getProjectName() {
      request({
        url: "/api/project/project/name",
        method: "get",
        params: {
          id: this.$route.params.projectId,
        },
      }).then(({ data }) => {
        if (data.code === 0) {
          this.projectName = data.data;
          document.title = this.projectName + " - " + document.title;
        } else {
          ElMessage.error(data.msg);
        }
      });
    },

    /**
     * 拖拽节点成功事件
     * @param draggingNode 被拖拽的
     * @param dropNode  拖拽进的节点
     * @param dropType 在dropNode的哪个方位 before、after、inner
     * @param ev
     */
    onNodeDrop(draggingNode, dropNode, dropType, ev) {
      console.log(draggingNode, dropNode, dropType, ev);

      this.orderData.id = draggingNode.data.id;
      this.orderData.type = draggingNode.data.type;

      // 直接拖到另一个文件夹上
      if (dropType === "inner") {
        this.orderData.parentFolderId = dropNode.data.id;
        this.orderData.order =
          dropNode.data.children == null || dropNode.data.children.length === 0
            ? 0
            : dropNode.data.children[dropNode.data.children.length - 1].order +
              1000;
      } else {
        let parentData = dropNode.parent.data;
        this.orderData.parentFolderId =
          parentData === undefined ? null : parentData.id;
        let childrenData =
          this.orderData.parentFolderId == null
            ? parentData
            : parentData.children;
        let index = -1;
        for (let i = 0; i < childrenData.length; i++) {
          if (childrenData[i].id === draggingNode.data.id) {
            index = i;
            break;
          }
        }
        if (index === -1) {
          throw new Error("移动文档失败");
        }

        if (index === 0 || index === childrenData.length - 1)
          this.orderData.order =
            dropNode.data.order + (dropType === "before" ? -1000 : 1000);
        else this.setOrderBetween(index - 1, index + 1, childrenData);
      }

      // request
      request({
        url: "/api/project/doc/reorder",
        method: "post",
        data: this.orderData,
      });

      draggingNode.data.order = this.orderData.order;
      draggingNode.data.parentFolderId = this.orderData.parentFolderId;

      this.orderData = {};
    },

    setOrderBetween(preIndex, postIndex, childrenData) {
      let preOrder = childrenData[preIndex].order;
      let postOrder = childrenData[postIndex].order;
      let midOrder = (+preOrder + postOrder) >> 1;
      if (midOrder !== preOrder && midOrder !== postOrder) {
        // 两节点的order差大于2，例如 0和2中间可以存在一个(int)order
        this.orderData.order = midOrder;
      } else {
        //
        let reorderArray = [];
        childrenData[preIndex + 1].order = childrenData[preIndex].order + 1000;
        this.orderData.order = childrenData[preIndex + 1].order;
        for (let i = postIndex; i < childrenData.length; i++) {
          childrenData[i].order = childrenData[i - 1].order + 1000;
          reorderArray.push({
            id: childrenData[i].id,
            type: childrenData[i].type,
            order: childrenData[i].order,
          });
        }

        // 修改重新排序的order
        request({
          url: "/api/project/doc/reorder_batch",
          method: "post",
          data: reorderArray,
        });
      }
    },

    saveLastExpandedNodeKeys() {
      let { nodesMap } = this.$refs["treeRef"].store;
      let lastExpandIds = [];
      for (let item of Object.values(nodesMap)) {
        if (item.expanded) {
          lastExpandIds.push(item.data.id);
        }
      }
      nodesMap = {};

      this.expandedKeys = lastExpandIds;
    },

    addTab(data) {
      if (data.type === "folder") return;

      this.selectTabName = data.id;

      let isExist = false;
      for (let i = 0; i < this.tabPlaneData.length; i++) {
        if (this.tabPlaneData[i].id === data.id) {
          isExist = true;
          break;
        }
      }

      if (!isExist) {
        this.tabPlaneData.push({
          id: data.id,
          name: data.name,
          type: data.type,
        });
        store.state.planeTabIsModified.push(false);
      }
    },
  },
  created() {
    // console.log(this.$route.params.projectId)
    this.getDocList(true);
    this.getProjectName();
  },
};
</script>

<template>
  <!--  重命名dialog-->
  <el-dialog
    v-model="renameDialogVisible"
    :title="
      '重命名' +
      (renameData.type === 'folder' ? '目录' : '文档') +
      renameDialogTitleSuffix
    "
    width="35%"
    @close="
      () => {
        renameData.name = '';
        renameData.id = null;
      }
    "
  >
    <el-form ref="renameFormRef" :rules="createRules" :model="renameData">
      <el-form-item label="新名字" prop="name">
        <el-input maxlength="64" v-model="renameData.name" />
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button type="primary" @click="renameDoc"> 修改 </el-button>
    </template>
  </el-dialog>

  <!--  create dialog-->
  <el-dialog
    v-model="createDialogVisible"
    width="35%"
    @close="
      () => {
        createData.name = '';
        createData.type = 'api';
      }
    "
  >
    <el-tabs v-model="createDialogTabName">
      <el-tab-pane label="新建文档" name="doc">
        <el-form ref="docFormRef" :rules="createRules" :model="createData">
          <el-form-item label="文档名字" prop="name">
            <el-input maxlength="64" v-model="createData.name" />
          </el-form-item>
          <el-form-item label="文档类型" prop="type">
            <el-radio-group v-model="createData.type">
              <el-radio value="api">接口文档</el-radio>
              <el-radio value="markdown">Markdown文档</el-radio>
              <el-radio value="rtf">富文本</el-radio>
              <el-radio value="mindmap">思维导图</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-form>
      </el-tab-pane>
      <el-tab-pane label="新建目录" name="folder">
        <el-form ref="folderFormRef" :rules="createRules" :model="createData">
          <el-form-item label="目录名字" prop="name">
            <el-input maxlength="64" v-model="createData.name" />
          </el-form-item>
        </el-form>
      </el-tab-pane>
    </el-tabs>
    <template #footer>
      <el-button type="primary" @click="createDoc">
        {{ createDialogTabName === "doc" ? "新建文档" : "新建目录" }}
      </el-button>
    </template>
  </el-dialog>

  <el-container>
    <el-aside width="300px" class="my-aside">
      <el-text size="large" style="color: #303133; font-weight: bold">
        <br />
        {{ projectName }}
        <br />
      </el-text>

      <el-divider />

      <el-tree
        ref="treeRef"
        :data="data"
        :props="defaultProps"
        empty-text="还没有任何文件，快去创建吧"
        style="background-color: rgb(245, 247, 249)"
        draggable
        v-loading="treeLoading"
        @node-drop="onNodeDrop"
        :allow-drop="
          (draggingNode, dropNode, type) => {
            return type === 'inner' ? dropNode.data.type === 'folder' : true;
          }
        "
        :default-expanded-keys="expandedKeys"
        node-key="id"
      >
        <template #default="{ node, data }">
          <el-row
            style="width: 100%; text-align: left"
            @mouseover="moreVisibleList[node.id] = true"
            @mouseout="moreVisibleList[node.id] = false"
            class="my-row"
            @click="addTab(data)"
          >
            <el-col :span="2">
              <el-icon size="large">
                <FolderOpened v-if="data.type === 'folder'" />
                <Key v-else-if="data.type === 'api'" />
                <Tickets v-else-if="data.type === 'markdown'" />
                <mind-mapping
                  theme="outline"
                  size="24"
                  fill="#9b9b9b"
                  strokeLinecap="square"
                  v-else-if="data.type === 'mindmap'"
                />
                <Document v-else />
              </el-icon>
            </el-col>

            <el-col :span="20">
              <el-text size="large">{{ node.label }}</el-text>
            </el-col>

            <el-col :span="2">
              <el-tooltip placement="bottom" effect="light">
                <el-icon v-show="moreVisibleList[node.id]" size="large">
                  <MoreFilled />
                </el-icon>
                <template #content>
                  <span v-if="data.type === 'folder'">
                    <el-button plain text @click="openCreateDialog('doc', data)"
                      >新建文件</el-button
                    >
                    <br />
                    <el-button
                      plain
                      text
                      @click="openCreateDialog('folder', data)"
                      >新建目录</el-button
                    >
                    <br />
                  </span>
                  <el-button plain text @click="openRenameDialog(data)"
                    >重命名</el-button
                  >
                  <br />
                  <el-button plain text @click="deleteDoc(data)"
                    >删除</el-button
                  >
                </template>
              </el-tooltip>
            </el-col>
          </el-row>
        </template>
      </el-tree>

      <br />
      <el-tooltip placement="top" effect="light" trigger="click">
        <el-button
          plain
          size="large"
          round
          auto-insert-space
          color="#d9ecff"
          style="color: #73767a; width: 90%"
        >
          <el-icon>
            <Plus />
          </el-icon>
          新建
        </el-button>
        <template #content>
          <el-button plain text @click="openCreateDialog('doc', null)">
            <el-icon size="large">
              <DocumentAdd />
            </el-icon>
            新建文件
          </el-button>
          <br />
          <el-button plain text @click="openCreateDialog('folder', null)">
            <el-icon size="large">
              <FolderAdd />
            </el-icon>
            新建目录
          </el-button>
        </template>
      </el-tooltip>
      <!--      <el-button @click="onTest">test</el-button>-->
    </el-aside>

    <el-main class="my-main">
      <EditTab
        :tab-plane-data="tabPlaneData"
        :select-tab-name="selectTabName"
      />
    </el-main>
  </el-container>
</template>

<style scoped>
.my-aside {
  height: calc(100vh - 60px);
  background-color: rgb(245, 247, 249);
  border-right-style: solid;
  border-right-color: #e9e9eb;
  border-right-width: 1px;
  text-align: center;
}

.my-main {
  height: calc(100vh - 60px);
}

.my-tree-node {
  height: 30px;
}

.my-row:hover {
  background-color: #fdf6ec;
}
</style>